package dm.ast.model.gen;

import dm.ast.*;
import dm.ast.model.gen.factory.BaseModelFactory;
import dm.ast.model.gen.factory.ComplexityModel;
import dm.ast.model.gen.factory.SelEleModelFactory;
import test.utility.Randomly;

import java.util.List;

/**
 * 根据模板AST生成查询列
 */
public class SelectElementGen extends ASTGenBase{

    @Override
    public DmASTNode gen(int astLevel, int wid_t, int dep_t) {
        ComplexityModel model = SelEleModelFactory.elementModels(wid_t , dep_t);
        return genByModel(astLevel , wid_t , dep_t , model, testFlags);
    }

    //生成指定个数的查询列
    //@wid_t ,总宽度
    //@dep_t , 总深度
    //@fields,查询列个数
    public static DmASTNode gen(int astLevel , int wid_t , int dep_t ,int fields , boolean[] testFlags){
        ComplexityModel model = BaseModelFactory.defaultModel(wid_t , dep_t , fields);
        return genByModel(astLevel , wid_t , dep_t , model, testFlags);
    }

    //update
    public static DmASTNode gen(int astLevel , int wid_t , int dep_t , int fields , boolean[] testFlags, List<DmDataType> selTypes){
        ComplexityModel model = BaseModelFactory.defaultModel(wid_t , dep_t , fields);
        return genByModel(astLevel , wid_t , dep_t , model, testFlags,selTypes);
    }

    //根据模型生成查询列部分
    private static DmSelectElements genByModel(int astLevel , int wid_t , int dep_t , ComplexityModel model , boolean[] testFlags){
        DmSelectElements selectElements = new DmSelectElements();
        selectElements.setTargetWidt(wid_t);
        selectElements.setTargetDept(dep_t);

        ExpressionGen expressionGen = new ExpressionGen();
        expressionGen.setTestFlags(testFlags);
        int tmp_widt = 0;
        boolean rownumUsedFlag = false;

        for (int i = 0; i < model.count; i++) {
            tmp_widt = model.comps[i].wid_t;
            if(tmp_widt > 0){
                DmExpression element;
                //小概率生成一个rownum查询列
                //todo
                //需要调整标志的读取方法
                if(model.comps[i].dep_t == 0){
                    System.out.println("55555");
                }
                if(!rownumUsedFlag && testFlags[BaseModelFactory.FLAG_ROWNUM] && Randomly.getBooleanWithRatherLowProbability()){
                    rownumUsedFlag = true;
                    element = new DmColumn("ROWNUM" , new DmColumnType("int"));

                } else{  //element DmCast DmColum DmConstat
                    element = (DmExpression)expressionGen.genSelElements(astLevel, tmp_widt , model.comps[i].dep_t);
                }
                selectElements.addElement(element);
            }else {  //中间宽度为0，那么后续的宽度也为0，不必考虑
                break;
            }
        }
        return selectElements;
    }

    //update
    private static DmSelectElements genByModel(int astLevel , int wid_t , int dep_t , ComplexityModel model , boolean[] testFlags,List<DmDataType> selTypes){
        DmSelectElements selectElements = new DmSelectElements();
        selectElements.setTargetWidt(wid_t);
        selectElements.setTargetDept(dep_t);

        ExpressionGen expressionGen = new ExpressionGen();
        expressionGen.setTestFlags(testFlags);
        int tmp_widt = 0;
        boolean rownumUsedFlag = false;
        for (int i = 0; i < model.count; i++) {
            tmp_widt = model.comps[i].wid_t;
            if(tmp_widt > 0){
                DmExpression element;
                //小概率生成一个rownum查询列
                //todo
                //需要调整标志的读取方法
                if(!rownumUsedFlag && testFlags[BaseModelFactory.FLAG_ROWNUM] && Randomly.getBooleanWithRatherLowProbability()){
                    rownumUsedFlag = true;
                    element = new DmColumn("ROWNUM" , new DmColumnType("int"));

                } else{
                    DmDataType rType = selTypes.get(i);
                    element = (DmExpression)expressionGen.genSelElements(astLevel, tmp_widt , model.comps[i].dep_t,rType);
                }
                selectElements.addElement(element);
            }else {  //中间宽度为0，那么后续的宽度也为0，不必考虑
                break;
            }
        }
        return selectElements;
    }

    //查询列有表的列构成
    //1、此时忽略模板中查询列出现的子查询（depth>1),表达式（width>1)
    //2、且不使用rownum
    //目前用于带gourpby的查询语句
    //@fiels:表示预期查询列的个数，如果为0，表示可随机取值。
    public static DmSelectElements genColumns(int astLevel , int wid_t , int dep_t , int fields){
        DmSelectElements selectElements = new DmSelectElements();

        int size = fields;
        if(size == 0){
            ComplexityModel model = SelEleModelFactory.elementModels(wid_t , dep_t);
            size = model.count;
        }

        //由于忽略模板中查询列出现的子查询（depth>1),表达式（width>1)
        //所以宽度为模板中查询列的个数，深度为1
        selectElements.setTargetWidt(size);
        selectElements.setTargetDept(1);

        for (int i = 0; i < size; i++) {
            selectElements.addElement(ExpressionGen.genRandColumn());
        }
        return selectElements;
    }


}
